<script>
    //让调用call（）的方法立即执行
    // call（）第一个参数 为新的this指向
    // 实现 call（） 方法的底层原理 
    //通过重写 object的原型 覆盖之前的方法
   Object.prototype.call = function(obj,...ags){
        //this();//立即调用函数
        // this指向为假 时 让其指向  widow
        if(obj === undefined || obj === null) obj = window
        // 给其 调用着 存放到 obj（修改后的this所指向的元素）中 
        obj.temFn = this 
        const a = obj.temFn(...ags) //调用 存放在新的运行环境下的 函数 并将实参列表传入 拿到返回值
        //删除 在 obj上面的方法
        delete obj.temFn
        //返回 在新的运行环境下运行函数 的返回值
        return a
    }
    obj = {a:1}
    function add(a,b){
        console.log(this);
        console.log(a+b);
    }
    add()
    add.call(obj,1,2)   

    //apply()
     // 实现 apply() 方法的底层原理 
    //通过重写 object的原型 覆盖之前的方法
   Object.prototype.apply = function(obj,ags){
        //this();//立即调用函数
        // this指向为假 时 让其指向  widow
        if(obj === undefined || obj === null) obj = window
        // 给其 调用着 存放到 obj（修改后的this所指向的元素）中 
        obj.temFn = this 
        const a = obj.temFn(...ags) //调用 存放在新的运行环境下的 函数 并将实参展开传入 拿到返回值
        //删除 在 obj上面的方法
        delete obj.temFn
        //返回 在新的运行环境下运行函数 的返回值
        return a
    }
    add.apply(obj,[1,2])  
    // bind() 不会让函数立即指向 返回一个新的函数
     // 实现 bind() 方法的底层原理 
    //通过重写 object的原型 覆盖之前的方法

    Object.prototype.bind=function(obj,...ags){
        thas = this //保存 调用此方法的函数
        return function(...ags2){ //返回一个新函数
            return thas.call(obj,...ags,...ags2) // 通过call方法 修改this
        }

    }
    function fun(a){
        console.log(this);
    }
    fun.call( undefined, 1,2)


</script>